package io.adrainty.bolee.file.adapter.impl;

import io.adrainty.bolee.file.adapter.FileStorageAdapter;
import io.adrainty.bolee.file.handler.FileStorageHandler;
import io.adrainty.bolee.file.models.entity.FileEntity;
import io.adrainty.bolee.file.models.entity.FilePartEntity;
import io.adrainty.bolee.file.models.valobj.FileStorageEnum;
import io.adrainty.bolee.framework.commons.basic.ResponseCode;
import io.adrainty.bolee.framework.commons.exception.AppException;
import io.adrainty.bolee.framework.commons.utils.EnumUtil;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author AdRainty
 * @version V1.0.0
 * @since 2025/8/18 上午12:00
 */

@Component
public class FileStorageAdapterImpl implements FileStorageAdapter {

    private final Map<FileStorageEnum, FileStorageHandler> handlerMap;

    private static final FileStorageEnum DEFAULT_STORAGE = FileStorageEnum.TENCENT_COS;

    public FileStorageAdapterImpl(List<FileStorageHandler> handlerList) {
        handlerMap = new HashMap<>(handlerList.size());
        for (FileStorageHandler handler : handlerList) {
            handlerMap.put(handler.supportStorage(), handler);
        }
    }

    private FileStorageHandler strictGetStorageHandler(FileStorageEnum storageEnum) {
        if (storageEnum == null) storageEnum = DEFAULT_STORAGE;
        FileStorageHandler handler = handlerMap.get(storageEnum);
        if (handler == null) {
            throw new AppException(ResponseCode.FILE_STORAGE_NOT_SUPPORT);
        }
        return handler;
    }

    @Override
    public String uploadFile(FileEntity fileVO, InputStream inputStream) {
        FileStorageHandler handler = strictGetStorageHandler(fileVO.getStoreFlag());
        return handler.uploadFile(fileVO.getSuffix(), fileVO.getFileName(), fileVO.getBucketName(), fileVO.getAutoCatalog(), inputStream);
    }

    @Override
    public FileEntity initiateMultipartUpload(FileEntity fileVO) {
        FileStorageHandler handler = strictGetStorageHandler(fileVO.getStoreFlag());
        return handler.initiateMultipartUpload(fileVO.getSuffix(), fileVO.getFileName(), fileVO.getBucketName(), fileVO.getAutoCatalog());
    }

    @Override
    public String uploadPart(FilePartEntity filePartVo, InputStream inputStream) {
        FileStorageHandler handler = strictGetStorageHandler(filePartVo.getStoreFlag());
        return handler.uploadPart(filePartVo.getUploadId(), filePartVo.getFileName(), filePartVo.getPartNumber(), filePartVo.getPartSize(), filePartVo.getBucketName(), inputStream);
    }

    @Override
    public String completeMultipartUpload(FileEntity fileVO) {
        FileStorageHandler handler = strictGetStorageHandler(fileVO.getStoreFlag());
        return handler.completeMultipartUpload(fileVO.getUploadId(), fileVO.getPartETags(), fileVO.getFileName(), fileVO.getBucketName());
    }

    @Override
    public InputStream downloadFile(String storeFlag, String bucketName, String pathUrl) {
        FileStorageEnum storageEnum = EnumUtil.getEnumConstants(storeFlag, FileStorageEnum.class);
        FileStorageHandler handler = strictGetStorageHandler(storageEnum);
        return handler.downloadFile(bucketName, pathUrl);
    }

    @Override
    public void delete(String storeFlag, String bucketName, String pathUrl) {
        FileStorageEnum storageEnum = EnumUtil.getEnumConstants(storeFlag, FileStorageEnum.class);
        FileStorageHandler handler = strictGetStorageHandler(storageEnum);
        handler.delete(bucketName, pathUrl);
    }

    @Override
    public void deleteBatch(String storeFlag, String bucketName, List<String> pathUrls) {
        FileStorageEnum storageEnum = EnumUtil.getEnumConstants(storeFlag, FileStorageEnum.class);
        FileStorageHandler handler = strictGetStorageHandler(storageEnum);
        handler.deleteBatch(bucketName, pathUrls);
    }

    @Override
    public String getFileContent(String storeFlag, String bucketName, String pathUrl) {
        FileStorageEnum storageEnum = EnumUtil.getEnumConstants(storeFlag, FileStorageEnum.class);
        FileStorageHandler handler = strictGetStorageHandler(storageEnum);
        return handler.getFileContent(bucketName, pathUrl);
    }

    @Override
    public String getReadablePath(String storeFlag, String bucketName, String pathUrl) {
        FileStorageEnum storageEnum = EnumUtil.getEnumConstants(storeFlag, FileStorageEnum.class);
        FileStorageHandler handler = strictGetStorageHandler(storageEnum);
        return handler.getReadablePath(bucketName, pathUrl);
    }

}
